package teil4;

public class Mathe
{
    public static boolean isAbundant(int toCheck)
    {
        if (toCheck > 1)
        {
            return toCheck < getSummeAllerTeiler(toCheck);
        }
        return false;
    }

    public static Integer[] calcAbundants(int upperBoundary)
    {
        int zaehler = 0;
        int k = 0;
        for (int i = 2; i <= upperBoundary; i++)
        {
            if (isAbundant(i))
            {
                zaehler++;
            }
        }
        Integer[] abundant = new Integer[zaehler];
        for (int i = 2; i <= upperBoundary; i++)
        {
            if (isAbundant(i))
            {
                abundant[k] = i;
                k++;
            }
        }
        return abundant;
    }

    public static boolean isDeficient(int toCheck)
    {
        if (toCheck == 1)
        {
            return true;
        }
        if (isPrime(toCheck))
        {
            return true;
        }
        if (toCheck > 0)
        {
            return toCheck > getSummeAllerTeiler(toCheck);
        }
        return false;
    }

    public static Integer[] calcDeficients(int upperBoundary)
    {
        int zaehler = 0;
        int k = 0;
        for (int i = 1; i <= upperBoundary; i++)
        {
            if (isDeficient(i))
            {
                zaehler++;
            }
        }
        Integer[] deficient = new Integer[zaehler];

        for (int i = 1; i <= upperBoundary; i++)
        {
            if (isDeficient(i))
            {
                deficient[k] = i;
                k++;
            }
        }
        return deficient;
    }

    public static boolean isPerfect(int toCheck)
    {
        if (toCheck > 1)
        {
            return toCheck == getSummeAllerTeiler(toCheck);
        }
        return false;
    }

    public static Integer[] calcPerfects(int upperBoundary)
    {
        int zaehler = 0;
        int k = 0;
        for (int i = 2; i <= upperBoundary; i++)
        {
            if (isPerfect(i))
            {
                zaehler++;
            }
        }
        Integer[] perfect = new Integer[zaehler];
        for (int i = 2; i <= upperBoundary; i++)
        {
            if (isPerfect(i))
            {
                perfect[k] = i;
                k++;
            }
        }
        return perfect;
    }

    public static boolean isNiven(int toCheck)
    {
        return (toCheck % quersumme(toCheck) == 0);
    }

    public static Integer[] calcNivenNumbers(int upperBoundary)
    {
        int zaehler = 0;
        int k = 0;
        for (int i = 1; i <= upperBoundary; i++)
        {
            if (isNiven(i))
            {
                zaehler++;
            }
        }
        Integer[] niven = new Integer[zaehler];
        for (int i = 1; i <= upperBoundary; i++)
        {
            if (isNiven(i))
            {
                niven[k] = i;
                k++;
            }
        }
        return niven;
    }

    public static boolean isPrime(int toCheck)
    {
        if (toCheck < 2)
        {
            return false;
        }
        else if (toCheck == 2)
        {
            return true;
        }
        else
        {
            /* Versuche toCheck mit der Zahl 2 zu teilen! */
            if (toCheck % 2 == 0)
            {
                return false;
            }
            /*
             * Versuche toCheck mit den ungeraden Zahlen von 3 bis sqrt(toCheck)
             * zu teilen!
             */
            for (int i = 3; i <= Math.sqrt(toCheck); i = i + 2)
            {
                if (toCheck % i == 0)
                {
                    return false;
                }
            }
            return true;
        }
    }

    public static Integer[] calcPrimes(int upperBoundary)
    {
        int zaehler = 0;
        int k = 0;
        for (int i = 2; i <= upperBoundary; i++)
        {
            if (isPrime(i))
            {
                zaehler++;
            }
        }
        Integer[] prime = new Integer[zaehler];
        for (int i = 2; i <= upperBoundary; i++)
        {
            if (isPrime(i))
            {
                prime[k] = i;
                k++;
            }
        }
        return prime;
    }

    public static boolean isPrimeTwin(int toCheckA, int toCheckB)
    {
        if (isPrime(toCheckA) && isPrime(toCheckB) && (toCheckB - toCheckA == 2))
        {
            return true;
        }
        return false;
    }

    public static Integer[] calcPrimeTwins(int upperBoundary)
    {
        int zaehler = 0;
        int j = 0;
        for (int i = 3, k = 5; k <= upperBoundary; i++, k++)
        {
            if (isPrimeTwin(i, k))
            {
                zaehler++;
            }
        }
        Integer[] primeTwins = new Integer[zaehler];
        for (int i = 3, k = 5; k <= upperBoundary; i++, k++)
        {
            if (isPrimeTwin(i, k))
            {
                primeTwins[j] = i;
                primeTwins[j + 1] = k;
                j = +2;
            }
        }
        return primeTwins;
    }

    private static int getSummeAllerTeiler(int toCheck)
    {
        int summeAllerTeiler = 1;
        for (int teiler = 2; teiler < toCheck; teiler++)
        {
            if (toCheck % teiler == 0)
            {
                summeAllerTeiler += teiler;
            }
        }
        return summeAllerTeiler;
    }

    public static int quersumme(int zahl)
    {
        if (zahl <= 9)
        {
            return zahl;
        }
        return zahl % 10 + quersumme(zahl / 10);
    }
}
